/* ------------------------------------------------------------------- SOURCE CODE: matrix Tom Annau ------------------------------------------------------------------- */ #include "matrix.hh" #include #include typedef double *double_ptr; /* ------------------------------------------------------------------- Constructors and destructors ------------------------------------------------------------------- */ matrix::matrix(int rows, int columns) { n_columns = columns; n_rows = rows; if (n_columns < 1 || n_rows < 1) { if (n_columns || n_rows) cerr << "ERROR: Attempt to create matrix of illegal dimension (" << rows << "x" << columns << ")\n"; n_rows = 0; n_columns = 0; value = NULL; } else { value = new double_ptr[rows]; for (register int i = 0; i < rows; i++) { value[i] = new double[columns]; memset(value[i], 0, columns * sizeof(double)); } } } matrix::matrix(const matrix& m) { n_columns = m.n_columns; n_rows = m.n_rows; if (m.value) { value = new double_ptr[n_rows]; for (register int i = 0; i < n_rows; i++) { value[i] = new double[n_columns]; memcpy(value[i], m.value[i], n_columns * sizeof(double)); } } } matrix::matrix(const vector& v) { if (v.dimension() == 0) { n_columns = 0; n_rows = 0; value = NULL; cerr << "ERROR: Attempt to construct matrix from zero-dimensional " "vector\n"; } else { n_columns = 1; n_rows = v.dimension(); value = new double_ptr[n_rows]; for (register int i = 0; i < n_rows; i++) { value[i] = new double[1]; *(value[i]) = v[i]; } } } void matrix::resize(int rows, int columns) { if (rows < 1 && columns < 1) if (rows && columns) { cerr << "ERROR: Attempt to resize matrix to illegal dimensions\n"; return; } if (rows == n_rows && columns == n_columns) return; if (value) { for (int i = 0; i < n_rows; i++) delete [] value[i]; delete [] value; } if (rows && columns) { value = new double_ptr[rows]; for (register int i = 0; i < rows; i++) { value[i] = new double[columns]; memset(value[i], 0, columns * sizeof(double)); } } else value = NULL; n_rows = rows; n_columns = columns; } matrix::~matrix(void) { for (int i = 0; i < n_rows; i++) delete [] value[i]; delete [] value; } /* ------------------------------------------------------------------- Assignment operators ------------------------------------------------------------------- */ matrix& matrix::operator = (const matrix& m) { copy_from(m); return *this; } /* ------------------------------------------------------------------- Logical operators ------------------------------------------------------------------- */ int matrix::operator ==(const matrix & m) const { if ( n_rows != m.n_rows || n_columns != m.n_columns ) return 0; for( int i=0; i (istream& in, matrix& m) { for (register int i = 0; i < m.n_rows; i++) in.read(m.value[i], m.n_columns * sizeof(double)); return in; } ostream& operator << (ostream& out, const matrix& m) { out << m.table_form() << CR; return out; } istream& operator >> (istream& in, matrix& m) { string input_line; int r = 0, c; while (!in.eof()) { in >> input_line; if (input_line[0] != '#' && !input_line.blank()) { if (r >= m.n_rows) { cerr << "ERROR: Matrix from input stream has too many rows\n"; return in; } input_line.strip_spaces(); int c = input_line.fields(); if (c != m.n_columns) { cerr << "ERROR: Matrix from input stream has wrong number " "of columns\n"; return in; } for (register int i = 0; i < c; i++) m.value[r][i] = input_line.field(i).to_double(); r++; } else if (input_line.blank()) break; } if (r != m.n_rows) { cerr << "ERROR: Matrix from input stream has too few rows\n"; } return in; } /* ------------------------------------------------------------------- Protected methods ------------------------------------------------------------------- */ void matrix::copy_from(const matrix& m) { if (check_dims(m)) for (register int i = 0; i < n_rows; i++) memcpy(value[i], m.value[i], n_columns * sizeof(double)); } void matrix::construct_from_string(string s) { n_rows = 0; n_columns = 0; value = NULL; if (s.blank()) return; int semicolons = s.frequency(";"); n_rows = semicolons + 1; value = new double_ptr[n_rows]; int l_pos = 0; for (int i = 0; i < n_rows; i++) { if (l_pos > s.len()) { cerr << "ERROR: When reading matrix from string, found terminal ';'\n"; return; } int r_pos = s.position(";", i + 1); if (r_pos == NOT_FOUND) r_pos = s.len(); vector v(s.middle(l_pos, r_pos - 1)); if (n_columns == 0) { n_columns = v.dimension(); if (n_columns == 0) { cerr << "ERROR: When reading matrix from string, first row is zero " "dimensional\n"; return; } for (register int i = 0; i < n_rows; i++) { value[i] = new double[n_columns]; memset(value[i], 0, n_columns * sizeof(double)); } } if (n_columns != v.dimension()) { cerr << "ERROR: When reading matrix from string, row vectors were " "of inconsistent length\n"; return; } else memcpy(value[i], v.to_double_ptr(), n_columns * sizeof(double)); l_pos = r_pos + 1; } }